package com.jiyongjun.component;

import com.aliyun.openservices.aliyun.log.producer.LogProducer;
import com.aliyun.openservices.aliyun.log.producer.Producer;
import com.aliyun.openservices.aliyun.log.producer.ProducerConfig;
import com.aliyun.openservices.aliyun.log.producer.ProjectConfig;
import com.aliyun.openservices.log.Client;
import com.jiyongjun.component.condition.ConditionalOnSetProperty;
import com.jiyongjun.component.config.LogBootstrapConfig;
import com.jiyongjun.component.config.LogSpringConfiguration;
import com.jiyongjun.component.config.slsak.DefaultLogSlsAccessAccountProvider;
import com.jiyongjun.component.config.slsak.LogSlsAccessAccountProvider;
import com.jiyongjun.component.core.impl.DubboWatchDogClientTemplate;
import com.jiyongjun.component.core.impl.DubboWatchDogServerTemplate;
import com.jiyongjun.component.core.impl.MethodWatchDogAspect;
import com.jiyongjun.component.exception.convertor.DefaultDubboConsumerExceptionConvertor;
import com.jiyongjun.component.exception.convertor.DefaultDubboProviderExceptionConvertor;
import com.jiyongjun.component.exception.convertor.DubboConsumerExceptionConvertor;
import com.jiyongjun.component.exception.convertor.DubboProviderExceptionConvertor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * <h2></h2>
 * <h3>描述：</h3>
 *
 * @author yongjun.jyj
 * @since 2022/7/14 23:13
 */
@Configuration
@ConditionalOnProperty(prefix = "sls.log", value = "enabled", havingValue = "true", matchIfMissing = true)
@Import(value = LogSpringConfiguration.class)
public class SlsLogConfiguration {
    @Autowired
    private LogSlsAccessAccountProvider slsAccessAccountProvider;
    @Autowired
    private LogBootstrapConfig logBootstrapConfig;

    @ConditionalOnMissingBean
    @Bean
    public DubboWatchDogServerTemplate dubboWatchDogServerTemplate() {
        return new DubboWatchDogServerTemplate();
    }

    @ConditionalOnMissingBean
    @Bean
    public DubboWatchDogClientTemplate dubboWatchDogClientTemplate() {
        return new DubboWatchDogClientTemplate();
    }

    @ConditionalOnMissingBean
    @Bean
    public DubboProviderExceptionConvertor dubboProviderExceptionConvertor() {
        return new DefaultDubboProviderExceptionConvertor();
    }

    @ConditionalOnMissingBean
    @Bean
    public DubboConsumerExceptionConvertor dubboConsumerExceptionConvertor() {
        return new DefaultDubboConsumerExceptionConvertor();
    }

    @Bean(name = "logSlsProducer", destroyMethod = "close")
    public Producer logSlsProducer() {
        ProjectConfig projectConfig = new ProjectConfig(logBootstrapConfig.getSlsProject(), logBootstrapConfig.getSlsEndpoint(),
                slsAccessAccountProvider.getAccessId(), slsAccessAccountProvider.getAccessKey());

        LogProducer producer = new LogProducer(new ProducerConfig());
        producer.putProjectConfig(projectConfig);

        return producer;
    }

    @Bean
    public Client logSlsClient() {
        return new Client(logBootstrapConfig.getSlsEndpoint(), logBootstrapConfig.getSlsAccessId(),
                logBootstrapConfig.getSlsAccessKey());
    }

    @ConditionalOnMissingBean
    @Bean
    public LogSlsAccessAccountProvider logSlsAccessAccountProvider(LogBootstrapConfig logBootstrapConfig) {
        return new DefaultLogSlsAccessAccountProvider(logBootstrapConfig);
    }

    @ConditionalOnSetProperty(prefix = "sls.log.biz", name = "disabled-log-api-types", unContains = "METHOD")
    @ConditionalOnMissingBean
    @Bean
    public MethodWatchDogAspect methodWatchDogAspect() {
        return new MethodWatchDogAspect();
    }
}
